package com.qf.base.util;

import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;


/**
 * @author 汤奇
 * @version V1.0
 * @Project BookPro
 * @Package com.qf.base.util
 * @Description: 线程池服务
 * @Date 2022/8/6 8:21
 */
public class SyncBatchCallUtil {
    /**
     * 线程池服务
     */
    private static ExecutorService executorService;

    static {
        //7个参数
        //核心线程数
        //计算密集型系统和IO密集型系统
        //计算密集型系统: 核心线程数设置为CPU核心数+1
        //IO密集型系统: 核心线程数设置为CPU核心数*2
        int corePoolSize = 4*2;
        //最大线程数
        int maxPoolSize = 10;
        //时间
        long keepAliveTime = 10;
        //时间单位
        TimeUnit unit = TimeUnit.SECONDS;
        //队列
        LinkedBlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<>();
        //工厂
        ThreadFactory threadFactory = new UserThreadFactory("QianFeng");
        //拒绝策略
        RejectedExecutionHandler handler = new UserRejectPolicy();
        //实例化线程池
        executorService = new ThreadPoolExecutor(corePoolSize,maxPoolSize,keepAliveTime,unit,workQueue,threadFactory,handler);
    }

    /**
     * 线程工厂
     */
    static class UserThreadFactory implements ThreadFactory {
        private final String namePrefix;
        private final AtomicInteger nextId = new AtomicInteger(1);

        public UserThreadFactory(String groupName) {
            this.namePrefix = "From" + UserThreadFactory.class.getName() + "-" + groupName + "-";
        }

        @Override
        public Thread newThread(Runnable r) {
            String name = namePrefix + nextId.getAndIncrement();
            Thread thread = new Thread(null, r, name);
            return thread;
        }
    }

        /**
         * 拒绝策略
         */
        static class UserRejectPolicy implements RejectedExecutionHandler{

            @Override
            public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
                System.out.println(SyncBatchCallUtil.class.getName()+"队列满了");
            }
        }

        /**
         * 自定义任务类
         */
        public static abstract class Task implements Runnable{
            /**
             * 任务调度的方法
             */
            public abstract void exe();

            /**
             * 内部封装CountDownLatch
             */
            private CountDownLatch countDownLatch;

            public void setCountDownLatch(CountDownLatch countDownLatch) {
                this.countDownLatch = countDownLatch;
            }

            @Override
            public void run() {
                //先执行任务再-1
                try {
                    exe();
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    countDownLatch.countDown();
                }
            }
        }

        /**
         * 创建一组任务
         */
        private static boolean createTasks(Task[] tasks){
            //给这组任务实例一个CountDownLatch
            //注意: 是一组任务对应的一个CountDownLatch对象
            CountDownLatch countDownLatch = new CountDownLatch(tasks.length);
            //给每一个任务设定相同的CountDownLatch对象
            for (int i = 0; i < tasks.length; i++) {
                tasks[i].setCountDownLatch(countDownLatch);
            }
            //每一个task类型其实都是Runnable
            //所以task应该用线程池启动
            for (int i = 0; i < tasks.length; i++) {
                //线程池启动每一个线程(任务)
                executorService.execute(tasks[i]);
            }
            //卡住当前线程
            try {
                countDownLatch.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
                return false;
            }
            return true;
        }

        /**
         * 给外界提供方法
         */
        public static boolean batch(Task ...tasks){
            return createTasks(tasks);
        }

}
